import subprocess
import sys
import os
from datetime import datetime
import shutil

def install_dependencies():
    import urllib.request
    try:
        import time
        # 检测VC++编译环境
        try:
            subprocess.check_output(['cl'], stderr=subprocess.STDOUT)
        except FileNotFoundError:
            print("未检测到VC++编译环境，开始自动安装Visual Studio Build Tools...")
            vs_buildtools_url = 'https://aka.ms/vs/17/release/vs_buildtools.exe'
            install_args = [
                'vs_buildtools.exe',
                '--quiet',
                '--wait',
                '--norestart',
                '--add',
                'Microsoft.VisualStudio.Workload.VCTools',
                '--includeRecommended'
            ]

            try:
                # 下载安装程序
                print("正在下载Visual Studio Build Tools...")
                for attempt in range(3):
                    try:
                        urllib.request.urlretrieve(vs_buildtools_url, 'vs_buildtools.exe')
                        break
                    except Exception as e:
                        if attempt == 2:
                            raise
                        print(f"下载失败，正在重试... ({attempt+1}/3)")
                        time.sleep(5)
                
                # 静默安装
                print("正在安装编译环境(大约需要5-10分钟)...")
                subprocess.run(install_args, check=True, timeout=1200)
            except subprocess.CalledProcessError as e:
                if e.returncode == 3010:
                    print("检测到需要重启，正在安排自动重启...")
                    with open('restart.bat', 'w') as f:
                        f.write(f'start /min cmd /c "{sys.argv[0]} && del restart.bat"')
                    os.system('restart.bat')
                    return True
                else:
                    print(f"安装失败，错误代码: {e.returncode}")
                    return False
            except subprocess.TimeoutExpired:
                print("安装超时，正在重试...")
                return False
            finally:
                if os.path.exists('vs_buildtools.exe'):
                    os.remove('vs_buildtools.exe')
            print("编译环境安装完成")
            
            # 添加手动安装指引
            print("\n手动安装指引：")
            print("1. 访问 https://aka.ms/vs/17/release/vs_buildtools.exe 下载安装程序")
            print("2. 使用管理员权限运行以下命令：")
            print(' '.join(install_args))
            print("编译环境安装完成")
                
            # 验证安装
            try:
                # 获取VS安装路径
                import winreg
                access_reg = winreg.ConnectRegistry(None, winreg.HKEY_LOCAL_MACHINE)
                
                # 尝试多个注册表路径
                vs_paths = []
                for version in ['17.0', '16.0', '15.0']:
                    try:
                        key_path = f'SOFTWARE\\WOW6432Node\\Microsoft\\VisualStudio\\SxS\\VS7'
                        vs_key = winreg.OpenKey(access_reg, key_path)
                        path = winreg.QueryValueEx(vs_key, version)[0]
                        vs_paths.append(path)
                        winreg.CloseKey(vs_key)
                    except Exception:
                        pass
                
                # 尝试默认安装路径
                default_paths = [
                    r'C:\Program Files\Microsoft Visual Studio\2022\BuildTools',
                    r'C:\Program Files (x86)\Microsoft Visual Studio\2019\BuildTools'
                ]
                vs_paths.extend(default_paths)
                
                # 遍历所有可能的路径
                print('开始扫描VC++环境路径:')
                for vs_path in vs_paths:
                    vcvars_path = os.path.join(vs_path, 'VC', 'Auxiliary', 'Build', 'vcvarsall.bat')
                    print(f'正在验证路径: {vcvars_path}')
                    if os.path.exists(vcvars_path):
                        try:
                            print(f'尝试配置环境变量: {vcvars_path}')
                            subprocess.run(f'"{vcvars_path}" x64 -vcvars_ver=14.29', shell=True, check=True)
                            print(f'成功配置VC++环境变量: {vcvars_path}')
                            break
                        except Exception as e:
                            print(f'路径配置失败: {str(e)}')
                else:
                    raise FileNotFoundError('未找到有效的VC++环境变量路径')
                
                # 二次验证环境变量
                print('正在验证环境变量配置...')
                env_check = subprocess.check_output(['cl'], stderr=subprocess.STDOUT)
                print('环境变量验证通过:', env_check.decode('gbk')[:200])
                
                # 重试验证编译器
                for retry in range(3):
                    try:
                        subprocess.check_output(['cl'], stderr=subprocess.STDOUT)
                        print('编译环境验证成功')
                        return True
                    except Exception as verify_error:
                        if retry == 2:
                            raise
                        print(f'环境验证失败，正在重试... ({retry+1}/3)')
                        time.sleep(5)
            except Exception as e:
                print(f'最终环境验证失败: {str(e)}')
                print('请检查: 1.系统是否已重启 2.环境变量是否包含VC++路径')
                return False
            
            # 这个异常处理已被前面的更具体异常处理覆盖，可以移除
            # 如果需要处理其他未捕获的异常，应该使用更具体的异常类型
            # 移除此处的OSError异常处理，因为它已被前面的更具体异常处理覆盖
            # 如果需要处理特定的系统错误，应该在更早的try-except块中处理
        except Exception as e:
            if isinstance(e, FileNotFoundError):
                print("未检测到VC++编译环境，请先安装Microsoft C++生成工具：")
                print("https://visualstudio.microsoft.com/zh-hans/visual-cpp-build-tools/")
                return False
            raise
            
        # 添加--prefer-binary参数避免源码编译
        for attempt in range(3):
            try:
                subprocess.run([sys.executable, '-m', 'pip', 'install', '-r', 'requirements.txt', '--prefer-binary'], check=True)
                print("依赖安装成功")
                break
            except subprocess.CalledProcessError as e:
                if attempt == 2:
                    raise
                print(f"依赖安装失败，正在重试... ({attempt+1}/3)")
                time.sleep(5)
        
        # 添加并验证requests依赖
        for retry in range(3):
            try:
                subprocess.run([sys.executable, '-m', 'pip', 'install', 'requests'], check=True)
                import requests
                break
            except Exception as e:
                if retry == 2:
                    raise
                print(f"requests安装失败，正在重试... ({retry+1}/3)")
                time.sleep(5)
    except Exception as e:
        print(f"requests安装失败: {str(e)}")
        return False

def run_tests():
    try:
        subprocess.run([sys.executable, '-m', 'pytest', 'tests/'], check=True)
        print("测试通过")
        return True
    except subprocess.CalledProcessError:
        print("测试失败")
        return False
    except FileNotFoundError:
        print("未找到测试目录，跳过测试")
        return True

def build_executable():
    version = datetime.now().strftime("v1.0.0_%Y%m%d_%H%M")
    build_cmd = [
        'pyinstaller',
        '--onefile',
        '--noconsole',
        '--name', f'OnmyojiAuto_{version}',
        '--add-data', 'templates/*;templates',
        '--add-data', 'config.json;.',
        'onmyoji_auto.py'
    ]
    
    try:
        subprocess.run(build_cmd, check=True)
        print("构建成功")
        
        # 创建压缩包
        shutil.make_archive(f'OnmyojiAuto_{version}', 'zip', 'dist')
        print(f"已生成压缩包：OnmyojiAuto_{version}.zip")
        return True
    except Exception as e:
        print(f"构建失败: {str(e)}")
        return False

if __name__ == '__main__':
    if not install_dependencies():
        sys.exit(1)
    
    if not run_tests():
        sys.exit(1)
        
    if not build_executable():
        sys.exit(1)